/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package hilos;

import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.Queue;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Todos los hilos y procesos deben ser lanzados en Nessy a través de esta clase
 * usando encolarHilo() de esta manera serán ejecutados secuencialmente
 * @author Felipe Serrano
 */
public class GestorHilos extends Thread{
    
    private Queue<Thread> colaHilos;
    private Thread hiloActivo;
    private HashMap<Long,Integer> tabla;
    
    
    public GestorHilos(){
        colaHilos = new ArrayDeque<>(20);
        hiloActivo = null;
        tabla = new HashMap<>();
    }

    @Override
    public void run() {
        long idActual;
        String nombre;
        try {
            while (true) {
                //DEBUG
                System.out.println("Numero de hilos: "+colaHilos.size());
                hiloActivo = colaHilos.poll();
                
                //Si hay hilos encolados ejecuta el primero
                if (hiloActivo != null) {
                    idActual = hiloActivo.getId();
                    nombre = hiloActivo.getName();
                    hiloActivo.start();
                    hiloActivo.join();
                    //DEBUG
                    System.out.println("Hilo "+hiloActivo.getName()+" terminado: "+tabla.get(idActual));
                    //Si una vez terminado el hilo, retornó con error cancelar
                    // todos los hilos siguientes a este.
                    if(tabla.get(idActual) != 0){
                        interrumpirHilos();
                    }
                    //Elimina la entrada asociada al hilo
                    tabla.remove(idActual);
                    
                //Si no hay hilos encolados esperar
                } else {
                    sleep(1000);
                }
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(GestorHilos.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Añade un hilo a la cola del gestor y será ejecutado cuando sea su turno
     * @param hilo a encolar para ejecucción
     */
    public void encolarHilo(HiloNessy hilo){
            hilo.enlazar(tabla);
            colaHilos.offer(hilo);
    }
    
   
    /**
     * Vacía la cola de hilos
     */
    public void interrumpirHilos(){
        while(!colaHilos.isEmpty()) colaHilos.remove();
    }
   
}
